﻿using System;
using Kugar.Core.ExtMethod;
using Kugar.Core.Web;
using Kugar.UI.Web.AdminLTE.Enums;
using Kugar.UI.Web.AdminLTE.Helpers;
using Microsoft.AspNetCore.Mvc.Razor;
using Newtonsoft.Json.Linq;

namespace Kugar.UI.Web.AdminLTE.PageControls.Helpers.ButtonExtMethod
{
    public static class ButtonExt
    {
        public static TButton Type<TButton>(this TButton src, ButtonTypeEnum type) where TButton : ButtonConfigBase
        {
            if (type== ButtonTypeEnum.submit)
            {
                src.Css("submitbutton");
                src._type = ButtonTypeEnum.button;
            }
            else
            {
                src.Attributes.SetOrReplaceAttr("type", type.ToStringEx());
                src._type = type;
            }

            
            

            return src;
        }

        public static TButton ShowModal<TButton>(this TButton btn,string url,string onSuccessCallback="",string onCloseCallback="",bool disabledShadeClose=false,bool refreshOnClose=false,bool refreshWholePageOnClose=false) where TButton : ICommandElement
        {
            btn.Command = new ButtonCmd_ShowModal().SetUrl(url).SetOnSuccessCallback(onSuccessCallback).SetOnCloseModalCallback(onCloseCallback).SetDisabledShadeClose(disabledShadeClose).SetOnRefreshPageOnClose(refreshOnClose).SetOnRefreshWholePageOnClose(refreshWholePageOnClose);

            return btn;
        }

        /// <summary>
        /// 显示一个取数窗体
        /// </summary>
        /// <typeparam name="TButton"></typeparam>
        /// <param name="btn"></param>
        /// <param name="url"></param>
        /// <param name="onSelectedCallback">选中数据后,触发该js回调</param>
        /// <param name="fillTitleFieldName">返回值中,需要填入文本框的字段名,一般是name或title</param>
        /// <param name="fillValueFieldName">返回值中,需要填入hidden的字段名,一般是ID</param>
        /// <param name="onShowCallback">显示取数窗体时触发回调</param>
        /// <param name="orderByColumnSelector">多选时,选中后排序列的筛选</param>
        /// <param name="orderbyType">多选时,选中区域的排序方式,,0=递增  1=递减</param>
        /// <returns></returns>
        public static TButton ShowDataPicker<TButton>(this TButton btn, string url, string onSelectedCallback, string fillTitleFieldName = "", string fillValueFieldName = "", string onShowCallback = "",string orderByColumnSelector="",int orderbyType=0,bool orderByNumeric=false, string afterSelectedCallback = "") where TButton: ICommandElement
        {
            btn.Command = new ButtonCmd_ShowDataPicker().SetUrl(url).OnSelectedCallback(onSelectedCallback).FillToTitle(fillTitleFieldName).FillToValue(fillValueFieldName).OnShowCallback(onShowCallback).SelectedAreaTableOrderbyKey(orderByColumnSelector,orderbyType==0, orderByNumeric);
            
            return btn;
        }

        /// <summary>
        /// 显示一个取数窗体
        /// </summary>
        /// <typeparam name="TButton"></typeparam>
        /// <param name="btn"></param>
        /// <param name="url"></param>
        /// <param name="fillConfig">自定义填充方式 ,key为控件的jquery selector,,value为返回值的字段名</param>
        /// <param name="fillTitleFieldName">返回值中,需要填入文本框的字段名,一般是name或title</param>
        /// <param name="fillValueFieldName">返回值中,需要填入hidden的字段名,一般是ID</param>
        /// <param name="onShowCallback">显示取数窗体时触发回调</param>
        /// <param name="orderByColumnSelector">多选时,选中后排序列的筛选</param>
        /// <param name="orderbyType">多选时,选中区域的排序方式,,0=递增  1=递减</param>
        /// <returns></returns>
        public static TButton ShowDataPicker<TButton>(this TButton btn, string url, JObject fillConfig, string fillTitleFieldName = "", string fillValueFieldName = "", string onShowCallback = "", string orderByColumnSelector = "", int orderbyType = 0, bool orderByNumeric = false,string afterSelectedCallback="") where TButton : ICommandElement
        {
            btn.Command = new ButtonCmd_ShowDataPicker().SetUrl(url).FillConfig(fillConfig).FillToTitle(fillTitleFieldName).FillToValue(fillValueFieldName).OnShowCallback(onShowCallback).SelectedAreaTableOrderbyKey(orderByColumnSelector, orderbyType == 0);

            return btn;
        }

        public static TButton ShowGeoPicker<TButton>(this TButton btn,string initAddress, string onSuccessCallback = "",(string fillSelector,string propName)[] fillConfig=null) where TButton : ICommandElement
        {
            btn.Command = new ButtonCmd_GeoPicker().InitAddress(initAddress).FillTo(fillConfig)
                .OnSuccessCallback(onSuccessCallback);

            return btn;
        }

        /// <summary>
        /// 弹出一个地理位置选择框,成功时回调的参数为 { lng: 经度, lat: 纬度  , loc: 经度+纬度的字符串}
        /// </summary>
        /// <typeparam name="TButton"></typeparam>
        /// <param name="btn"></param>
        /// <param name="initAddress"></param>
        /// <param name="onSuccessCallback"></param>
        /// <param name="fillConfig">选择后,自动填充数据到指定的控件中,</param>
        /// <returns></returns>
        public static TButton ShowGeoPicker<TButton>(this TButton btn, (decimal lng,decimal lat) initAddress, string onSuccessCallback = "", (string fillSelector, string propName)[] fillConfig = null) where TButton : ICommandElement
        {
            btn.Command = new ButtonCmd_GeoPicker().InitAddress(initAddress.lng,initAddress.lat).FillTo(fillConfig)
                .OnSuccessCallback(onSuccessCallback);

            return btn;
        }

        public static TButton ShowGeoPickerInitFromElelemtn<TButton>(this TButton btn, string initAddressFromElement, string onSuccessCallback = "", (string fillSelector, string propName)[] fillConfig = null) where TButton : ICommandElement
        {
            btn.Command = new ButtonCmd_GeoPicker().InitAddressFromElement(initAddressFromElement).FillTo(fillConfig)
                .OnSuccessCallback(onSuccessCallback);

            return btn;
        }



        /// <summary>
        /// 弹出一个文件上传框
        /// </summary>
        /// <typeparam name="TButton"></typeparam>
        /// <param name="btn"></param>
        /// <param name="uploadUrl">上传url</param>
        /// <param name="onSuccessCallback">上传成功后回调</param>
        /// <param name="onFailCallback">上传失败后回调</param>
        /// <param name="fielName">上传文件的字段名</param>
        /// <param name="autoRefreshPage">上传完是否自动刷新界面</param>
        /// <param name="accept">可上传的文件袋额MIME</param>
        /// <param name="fileMaxSize">可上传文件的大小上限</param>
        /// <returns></returns>
        public static TButton ShowUploadFile<TButton>(this TButton btn, string uploadUrl, string onSuccessCallback = "",
            string onFailCallback = "", string tips="" ,string fielName = "file", bool autoRefreshPage = false, string accept = "*/*",
            int fileMaxSize = 0) where TButton : ICommandElement
        {
            btn.Command=new ButtcnCmd_AjaxUploadFile().SetUploadUrl(uploadUrl).SetAccept(accept).SetAutoRefreshPage(autoRefreshPage).SetMaxFileSize(fileMaxSize).SetOnSuccessCallback(onSuccessCallback).SetOnFailCallback(onFailCallback).SetName(fielName).SetTips(tips);

            return btn;
        }

        /// <summary>
        /// 弹出一个文件浏览框,用于显示文件内容,如果是图片,则使用图片浏览器,如果是pdf,则调用浏览器自带的pdf浏览器
        /// </summary>
        /// <typeparam name="TButton"></typeparam>
        /// <param name="btn"></param>
        /// <param name="fileUrl"></param>
        /// <param name="title"></param>
        /// <param name="mime"></param>
        /// <param name="onSuccessCallback"></param>
        /// <param name="onFailCallback"></param>
        /// <returns></returns>
        public static TButton ShowFileViewer<TButton>(this TButton btn,string fileUrl,string title="查看",string mime="", string onSuccessCallback = "",
            string onCloseCallback = "") where TButton : ICommandElement
        {
            btn.Command=new ButtonCmd_ViewFile().SetUrl(fileUrl).SetMime(mime).SetTitle(title).OnCloseCallback(onCloseCallback).OnLoadSuccessCallback(onSuccessCallback);

            return btn;
        }

        public static TButton ExecuteCmd<TButton>(this TButton btn, string url, string cmdName,JObject args, string onSuccessCallback = "",string tips="",bool autoRefreshOnSuccess=false) where TButton : ICommandElement
        {
            btn.Command = new ButtonCmd_ExecuteCmd().SetArgs(args).SetMethodName(cmdName).SetCmdUrl(url).SetTips(tips).SetOnSuccessCallback(onSuccessCallback).AutoRefreshPage(autoRefreshOnSuccess);

            return btn;
        }


        /// <summary>
        /// 指定一个远程命令
        /// </summary>
        /// <typeparam name="TButton"></typeparam>
        /// <param name="btn"></param>
        /// <param name="url">Url地址</param>
        /// <param name="methodName">命令名,传递在methodName参数中</param>
        /// <param name="args">命令参数</param>
        /// <param name="onSuccessCallback">成功后回调</param>
        /// <param name="tips">调用前,弹出提示语句让用户确认是否执行</param>
        /// <param name="autoRefreshOnSuccess">成功后,是否刷新当前页,如果是Modal,则刷新modal页面,如果是page,则刷新当前page</param>
        /// <param name="autoRefreshWholePageOnSuccess">成功后,是否刷新整个页面,该参数用于当前执行命令的死Modal时,需要强制刷新整个页面时使用</param>
        /// <returns></returns>
        public static TButton ExecuteCmd<TButton>(this TButton btn, string url, string methodName, object args, string onSuccessCallback = "", string tips = "", bool autoRefreshOnSuccess = false,bool autoRefreshWholePageOnSuccess = false) where TButton : ICommandElement
        {
            btn.Command = new ButtonCmd_ExecuteCmd().SetArgs(args).SetMethodName(methodName).SetCmdUrl(url).SetTips(tips).SetOnSuccessCallback(onSuccessCallback).AutoRefreshPage(autoRefreshOnSuccess).AutoRefreshWholePage(autoRefreshWholePageOnSuccess);

            return btn;
        }

        public static TButton ExecuteCmd<TButton>(this TButton btn,Action<ButtonCmd_ExecuteCmd> configFunc) where TButton : ICommandElement
        {
            var cmd = new ButtonCmd_ExecuteCmd();
            configFunc(cmd);

            btn.Command = cmd;// new ButtonCmd_ExecuteCmd().SetArgs(args).SetCmdName(cmdName).SetCmdUrl(url).SetTips(tips).SetOnSuccessCallback(onSuccessCallback).SetAutoRefreshPage(autoRefreshOnSuccess);

            return btn;
        }

        //public static TButton Style<TButton>(this TButton btn, string styleName, string value)
        //    where TButton : ButtonConfigBase
        //{
        //    btn.Attrbutes.MergeAttr("style",$"{styleName}:{value}" );

        //    return btn;
        //}

        //public static TButton Css<TButton>(this TButton src, string className) where TButton : ButtonConfigBase
        //{
        //    if (string.IsNullOrWhiteSpace(className))
        //    {
        //        return src;
        //    }

        //    src.Attrbutes.Class(className);

        //    return src;
        //}

        //public static TButton Data<TButton>(this TButton src, string dataName, string value) where TButton : ButtonConfigBase
        //{
        //    if (!dataName.StartsWith("data-", StringComparison.CurrentCultureIgnoreCase))
        //    {
        //        dataName = "data-" + dataName;
        //    }
        //    src.Attrbutes.MergeAttr(dataName, value);

        //    return src;
        //}

        //public static TButton ID<TButton>(this TButton src, string id) where TButton : ButtonConfigBase
        //{
        //    src.Attrbutes.ID(id);

        //    return src;
        //}

        //public static TButton Attr<TButton>(this TButton src, string attrName, string value) where TButton : ButtonConfigBase
        //{
        //    src.Attrbutes.MergeAttr(attrName, value);

        //    return src;
        //}

        public static TButton Text<TButton>(this TButton src, string text) where TButton : ButtonConfigBase
        {
            src._title=text;

            return src;
        }

        public static TButton ButtonText<TButton>(this TButton src, Func<TButton,HelperResult> text) where TButton : ButtonConfigBase
        {
            src._title = text(src).ToHtmlString();

            return src;
        }

        public static TButton Color<TButton>(this TButton src, ColorPaletteEnum color) where TButton : ButtonConfigBase
        {
            src._color = color;

            return src;
        }

        public static TButton IconCss<TButton>(this TButton src, string css) where TButton : ButtonConfigBase
        {
            src._iconHtml = $"<i class=\"fa {css}\"></i>" ;

            return src;
        }

        public static TButton DisabledAfterClick<TButton>(this TButton src, bool isAutoDisabled = true) where TButton : ButtonConfigBase
        {
            src.Data("data-disabledafterclick", isAutoDisabled.ToStringEx());

            return src;
        }

        /// <summary>
        /// 跳转到一个连接
        /// </summary>
        /// <typeparam name="TButton"></typeparam>
        /// <param name="src"></param>
        /// <param name="url"></param>
        /// <param name="autoConcatForm">是否自动拼接当前link最近的form的字段值,目前只 type=link的按钮有效 </param>
        /// <param name="target"></param>
        /// <param name="openToBrowser">该参数用于在iframe模式下,直接打开一个连接,而非使用tab打开,用于比如打开一个下载连接</param>
        /// <returns></returns>
        public static TButton Href<TButton>(this TButton src,string url,LinkTargetType target= LinkTargetType.Self,bool openToBrowser=false, bool autoConcatForm = false) where TButton : ICommandElement
        {
            src.Command = new ButtonCmd_Goto().Url(url).Target(target).OpenToBrowser(openToBrowser).AutoConcatFormValue(autoConcatForm);

            return src;
        }

        /// <summary>
        /// 跳转到一个连接
        /// </summary>
        public static TButton Href<TButton>(this TButton src,Action<ButtonCmd_Goto> configFunc) where TButton : ICommandElement
        {
            if (configFunc==null)
            {
                throw new ArgumentNullException("configFunc");
            }

            var config=new ButtonCmd_Goto();

            configFunc(config);

            src.Command = config;// new ButtonCmd_Goto().SetUrl(url).SetTarget(target).SetOpenToBrowser(openToBrowser).SetAutoConcatFormValue(autoConcatForm);

            return src;
        }

        public static TButton OnClick<TButton>(this TButton src, string onclick) where TButton : ICommandElement
        {
            src.Command = new ButtonCmd_ClientClick().SetOnClickScript(onclick);

            return src;
        }

        public static TButton Hide<TButton>(this TButton src, bool isHide=true) where TButton : ButtonConfigBase
        {
            src._hide = isHide;

            return src;
        }
    }
}